package com.ouc.eddyAlgorithm.controller;

import com.ouc.common.annotation.Log;
import com.ouc.common.core.controller.BaseController;
import com.ouc.common.core.domain.AjaxResult;
import com.ouc.common.core.page.TableDataInfo;
import com.ouc.common.entity.NcData;
import com.ouc.common.enums.BusinessType;
import com.ouc.common.ncRead.NcDao;
import com.ouc.common.utils.Arith;
import com.ouc.common.utils.DateUtils;
import com.ouc.common.utils.poi.ExcelUtil;
import com.ouc.eddyAlgorithm.dao.PetNcDao;
import com.ouc.eddyAlgorithm.domain.AvisoEddy;
import com.ouc.eddyAlgorithm.mapper.AvisoEddyMapper;
import com.ouc.eddyAlgorithm.service.IAvisoEddyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import ucar.ma2.InvalidRangeException;
import ucar.nc2.NetcdfFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static java.lang.Float.NaN;

/**
 * avisoEddyController
 *
 * @author ouc
 * @date 2025-02-14
 */
@RestController
@RequestMapping("/eddyAlgorithm/avisoEddy")
public class AvisoEddyController extends BaseController {
  @Autowired
  private IAvisoEddyService avisoEddyService;

  @Autowired
  NcDao ncDao;

  @Autowired
  PetNcDao petNcDao;

  @Autowired
  AvisoEddyMapper avisoEddyMapper;

  /**
   * 查询avisoEddy列表
   */
  @PreAuthorize("@ss.hasPermi('eddyAlgorithm:avisoEddy:list')")
  @GetMapping("/list")
  public TableDataInfo list(AvisoEddy avisoEddy) {
    startPage();
    List<AvisoEddy> list = avisoEddyService.selectAvisoEddyList(avisoEddy);
    return getDataTable(list);
  }

  /**
   * 导出avisoEddy列表
   */
  @PreAuthorize("@ss.hasPermi('eddyAlgorithm:avisoEddy:export')")
  @Log(title = "avisoEddy", businessType = BusinessType.EXPORT)
  @PostMapping("/export")
  public void export(HttpServletResponse response, AvisoEddy avisoEddy) {
    List<AvisoEddy> list = avisoEddyService.selectAvisoEddyList(avisoEddy);
    ExcelUtil<AvisoEddy> util = new ExcelUtil<AvisoEddy>(AvisoEddy.class);
    util.exportExcel(response, list, "avisoEddy数据");
  }

  /**
   * 获取avisoEddy详细信息
   */
  @PreAuthorize("@ss.hasPermi('eddyAlgorithm:avisoEddy:query')")
  @GetMapping(value = "/{orderNumber}")
  public AjaxResult getInfo(@PathVariable("orderNumber") Integer orderNumber) {
    return success(avisoEddyService.selectAvisoEddyByOrderNumber(orderNumber));
  }

  /**
   * 新增avisoEddy
   */
  @PreAuthorize("@ss.hasPermi('eddyAlgorithm:avisoEddy:add')")
  @Log(title = "avisoEddy", businessType = BusinessType.INSERT)
  @PostMapping
  public AjaxResult add(@RequestBody AvisoEddy avisoEddy) {
    return toAjax(avisoEddyService.insertAvisoEddy(avisoEddy));
  }

  /**
   * 修改avisoEddy
   */
  @PreAuthorize("@ss.hasPermi('eddyAlgorithm:avisoEddy:edit')")
  @Log(title = "avisoEddy", businessType = BusinessType.UPDATE)
  @PutMapping
  public AjaxResult edit(@RequestBody AvisoEddy avisoEddy) {
    return toAjax(avisoEddyService.updateAvisoEddy(avisoEddy));
  }

  /**
   * 删除avisoEddy
   */
  @PreAuthorize("@ss.hasPermi('eddyAlgorithm:avisoEddy:remove')")
  @Log(title = "avisoEddy", businessType = BusinessType.DELETE)
  @DeleteMapping("/{orderNumbers}")
  public AjaxResult remove(@PathVariable Integer[] orderNumbers) {
    return toAjax(avisoEddyService.deleteAvisoEddyByOrderNumbers(orderNumbers));
  }


  /**
   * 读取aviso数据
   */
  @GetMapping("/readAvisoToMysql")
  public AjaxResult readAvisoToMysql(@RequestParam(value = "startDate") String startDate,
                                     @RequestParam(value = "endDate") String endDate) throws InvalidRangeException, IOException, ParseException {
    int eddyNum = 0;
    String[] paths = {
//        "C:\\MRTA3.2exp NRT\\Eddy_trajectory_nrt_3.2exp_anticyclonic_20180101_20240919.nc",
        "C:\\MRTA3.2exp NRT\\Eddy_trajectory_nrt_3.2exp_cyclonic_20180101_20240919.nc"
    };
    for (int n = 0; n < paths.length; n++) {
      NetcdfFile ncFile = NetcdfFile.open(paths[n]);
//      DecimalFormat df = new DecimalFormat("000");
      //Map<String, NcData> ncData = ncDao.getNcData(ncFile);
//      long end = System.currentTimeMillis();
//      System.out.println("用时 = " + (end - start));

    /*  DecimalFormat df = new DecimalFormat("000");
      float[] amplitudes = ncData.get("amplitude").getData1D();*/
//      List<AvisoEddy> petEddieList = new ArrayList<>();


//      StringBuilder sb = new StringBuilder();
      int type = 1;
      float longitude;
      float latitude;
      double effective_radius;
//      String longitudeFormat;
//      String latitudeFormat;
//      Date date = DateUtils.parseDate("2023-1-1");
//      int startIndex = ncDao.getNcTimeIndex(ncFile, date);
//      Map<String, NcData> ncData = petNcDao.getPetNcDataToMap(ncFile, startIndex, null);
//
//      int endIndex = ncDao.getVariable(ncFile, "time").getShape()[0];
//      List<String> ncTimeForList = ncDao.getNcTimeForList(ncFile, startIndex, endIndex);
      int tSize = 500000;
      int startIndex = 0;
      int endIndex = startIndex + tSize;
      while (endIndex - startIndex == tSize) {
        Map<String, NcData> ncData = petNcDao.getPetNcDataToMap(ncFile, startIndex, endIndex);
        float[] timeArr = ncData.get("time").getData1D();
        List<String> ncTimeForList = new ArrayList<>();
        Date date = DateUtils.parseDate("1950-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss");
        for (int i = 0; i < timeArr.length; i++) {
          if (timeArr[i] < 0) {
            timeArr[i] = Math.round(49710 + timeArr[i]);
          }
          ncTimeForList.add(DateUtils.parseDateToStr("yyyy-MM-dd", DateUtils.getTimeFormDifference(date, (int) timeArr[i] * 24)));
        }


//        List<String> ncTimeForList = ncDao.getNcTimeForList(ncFile, startIndex, endIndex);
        System.out.println("本轮查找到：" + startIndex + " ," + endIndex);
        startIndex += ncTimeForList.size();
        endIndex += tSize;

        for (int i = 0; i < ncTimeForList.size(); i++) {
          if (DateUtils.betweenDate(DateUtils.parseDate(ncTimeForList.get(i)), DateUtils.parseDate(startDate), DateUtils.parseDate(endDate))) {
            AvisoEddy petEddy = new AvisoEddy();
            longitude = ncData.get("longitude").getData1D()[i];
            latitude = ncData.get("latitude").getData1D()[i];
            effective_radius = Arith.div(ncData.get("effective_radius").getData1D()[i], 1000);
            /*if (ncFile.getLocation().matches(".*Anticyclonic.*")) {
              if (effective_radius * 2 <= 48) {
                type = 2;
              } else if (effective_radius * 2 > 48 && effective_radius * 2 < 96) {
                type = 4;
              } else if (effective_radius * 2 >= 96) {
                type = 6;
              }
            } else if (ncFile.getLocation().matches(".*Cyclonic.*")) {
              if (effective_radius * 2 <= 48) {
                type = 1;
              } else if (effective_radius * 2 > 48 && effective_radius * 2 < 96) {
                type = 3;
              } else if (effective_radius * 2 >= 96) {
                type = 5;
              }
            }
            if (longitude < 0) {
              longitude += 360;
            } else if (longitude > 360) {
              longitude -= 360;
            }
            if (latitude < 0) {
              latitude += 90;
            }*/
//          longitudeFormat = df.format(longitude);
//          latitudeFormat = df.format(latitude);

//            int lastDays = 1;
//            if (ncData.get("observation_number") != null) {
//              lastDays = (int) ncData.get("observation_number").getData1D()[i];
//            }
//            String observationNums = StringUtils.padl(lastDays, 4);
//          sb.append(1).append(type).append(longitudeFormat).append(latitudeFormat)
//              .append(StringUtils.remove(ncTimeForList.get(i), "-").substring(2)).append(observationNums);

//          sb.setLength(0);
//        System.out.println("102行时间 = " + (System.currentTimeMillis() - hang55));
            petEddy.setType(type);
            petEddy.setAmplitude((double) ncData.get("amplitude").getData1D()[i]);
            petEddy.setEffectiveArea(Arith.div(ncData.get("effective_area").getData1D()[i], 1000 * 1000, 6));
            petEddy.setEffectiveContourHeight((double) ncData.get("effective_contour_height").getData1D()[i]);
//          for (int j = 0; j < ncData.get("effective_contour_latitude").getData2D()[i].length; j++) {
//            ncData.get("effective_contour_latitude").getData2D()[i][j] = (float) Arith.round(ncData.get("effective_contour_latitude").getData2D()[i][j], 4);
//            ncData.get("effective_contour_longitude").getData2D()[i][j] = (float) Arith.round(ncData.get("effective_contour_longitude").getData2D()[i][j], 4);
//          }
//          petEddy.setEffectiveContourLatitude(Arrays.toString(ncData.get("effective_contour_latitude").getData2D()[i]));
//          petEddy.setEffectiveContourLongitude(Arrays.toString(ncData.get("effective_contour_longitude").getData2D()[i]));
            //  shape_error重新设置
            if (ncData.get("effective_contour_shape_error").getData1D()[i] < 0) {
              ncData.get("effective_contour_shape_error").getData1D()[i] = (float) Arith.add(ncData.get("effective_contour_shape_error").getData1D()[i], 128);
            }
            petEddy.setEffectiveContourShapeError((double) ncData.get("effective_contour_shape_error").getData1D()[i]);
            petEddy.setEffectiveRadius(effective_radius);
            petEddy.setInnerContourHeight((double) ncData.get("inner_contour_height").getData1D()[i]);
            petEddy.setLatitude((double) ncData.get("latitude").getData1D()[i]);
            petEddy.setLatitudeMax((double) ncData.get("latitude_max").getData1D()[i]);
            petEddy.setLongitude((double) ncData.get("longitude").getData1D()[i]);
            petEddy.setLongitudeMax((double) ncData.get("longitude_max").getData1D()[i]);
            petEddy.setNumContours((int) ncData.get("num_contours").getData1D()[i]);
            petEddy.setNumPointE((int) ncData.get("num_point_e").getData1D()[i]);
            petEddy.setNumPointS((int) ncData.get("num_point_s").getData1D()[i]);
            petEddy.setSpeedArea(Arith.div(ncData.get("speed_area").getData1D()[i], 1000 * 1000, 6));
            //  speed_average需要重新设置
            if (ncData.get("speed_average").getData1D()[i] < 0) {
              ncData.get("speed_average").getData1D()[i] = (float) Arith.add(ncData.get("speed_average").getData1D()[i], 6.5536);
            }
            petEddy.setSpeedAverage((double) ncData.get("speed_average").getData1D()[i]);
            petEddy.setSpeedContourHeight((double) ncData.get("speed_contour_height").getData1D()[i]);
//          for (int j = 0; j < ncData.get("speed_contour_latitude").getData2D()[i].length; j++) {
//            ncData.get("speed_contour_latitude").getData2D()[i][j] = (float) Math.round(ncData.get("speed_contour_latitude").getData2D()[i][j] * scaleFloat) / scaleFloat;
//            ncData.get("speed_contour_longitude").getData2D()[i][j] = (float) Math.round(ncData.get("speed_contour_longitude").getData2D()[i][j] * scaleFloat) / scaleFloat;
//          }
//        System.out.println("134行时间 = " + (System.currentTimeMillis() - hang55));
//          petEddy.setSpeedContourLatitude(Arrays.toString(ncData.get("speed_contour_latitude").getData2D()[i]));
//          petEddy.setSpeedContourLongitude(Arrays.toString(ncData.get("speed_contour_longitude").getData2D()[i]));
            //  shape_error重新设置
            if (ncData.get("speed_contour_shape_error").getData1D()[i] < 0) {
              ncData.get("speed_contour_shape_error").getData1D()[i] = (float) Arith.add(ncData.get("speed_contour_shape_error").getData1D()[i], 128);
            }
        /*long end148 = System.currentTimeMillis();
        System.out.println("end148 = " + (end148 - end119) / 1000.0);*/
//        System.out.println("143行时间 = " + (System.currentTimeMillis() - hang55));
            petEddy.setSpeedContourShapeError((double) ncData.get("speed_contour_shape_error").getData1D()[i]);
            petEddy.setSpeedRadius(Arith.div(ncData.get("speed_radius").getData1D()[i], 1000, 5));
            petEddy.setTime(DateUtils.dateTime(DateUtils.YYYY_MM_DD, ncTimeForList.get(i)));
//          for (int j = 0; j < ncData.get("uavg_profile").getData2D()[i].length; j++) {
//            ncData.get("uavg_profile").getData2D()[i][j] = Math.round(ncData.get("uavg_profile").getData2D()[i][j] * scaleFloat) / scaleFloat;
//          }
//          petEddy.setUavgProfile(Arrays.toString(ncData.get("uavg_profile").getData2D()[i]));
            petEddy.setTrack(ncData.get("track") == null ? null : (int) ncData.get("track").getData1D()[i]);
//          petEddy.setObservationFlag(ncData.get("observation_flag") == null ? null : (int) ncData.get("observation_flag").getData1D()[i]);
            petEddy.setObservationNumber(ncData.get("observation_number") == null ? null : (int) ncData.get("observation_number").getData1D()[i]);
            if (ncData.get("cost_association") != null && String.valueOf(ncData.get("cost_association").getData1D()[i]).equals("9.96921E36")) {
              ncData.get("cost_association").getData1D()[i] = NaN;
            }
            petEddy.setCostAssociation(ncData.get("cost_association") == null || Float.isNaN(ncData.get("cost_association").getData1D()[i]) ? null : (double) ncData.get("cost_association").getData1D()[i]);
//          petEddy.setAttribute(attribute);

//          petEddieList.add(petEddy);
            avisoEddyMapper.insertAvisoEddy(petEddy);
            eddyNum++;
          }
        }
        //petEddyService.insertByBatch(petEddieList);
        System.gc();
        System.out.println("本轮查找 " + timeArr.length + " 个涡旋，插入" + eddyNum);
      }
    }
    System.out.println("共查找并插入涡旋数目：" + eddyNum);
    return AjaxResult.success("共查找并插入涡旋数目：" + eddyNum);

  }
}
